/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.sap.tpcd.parserengine.wsdlfile;

import java.io.File;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.AbstractAction;
import javax.xml.namespace.QName;
import org.apache.neethi.All;
import org.apache.neethi.ExactlyOne;
import org.apache.neethi.Policy;
import org.apache.rampart.policy.RampartPolicyData;
import org.apache.woden.WSDLException;
import org.apache.woden.WSDLFactory;
import org.apache.woden.WSDLReader;
import org.apache.woden.wsdl20.Description;
import org.apache.woden.wsdl20.extensions.ExtensionElement;
import org.apache.woden.wsdl20.extensions.ExtensionRegistry;
import org.apache.woden.wsdl20.xml.BindingElement;
import org.apache.woden.wsdl20.xml.DescriptionElement;
import org.apache.woden.wsdl20.xml.InterfaceElement;
import org.apache.woden.wsdl20.xml.InterfaceOperationElement;
import org.apache.woden.wsdl20.xml.ServiceElement;
import org.apache.ws.secpolicy.WSSPolicyException;
import org.apache.ws.secpolicy.model.AbstractConfigurableSecurityAssertion;
import org.apache.ws.secpolicy.model.AbstractSecurityAssertion;
import org.w3c.dom.Element;

/**
 * 
 * @author Bouanani Meher
 */
public class WSDLParser {
	/*
	 * This Class Parse The WSDL File ExtensionElements contains policy
	 * defenition which will be used to detect different policy parts.
	 * BindingElemnt contain information about bindnig elements (interfaces ,
	 * Port , type, Methode, Action ..) WSDLConvertion will contain the target
	 * WSDLFile after converting it to WSDL2.0
	 */
	private ExtensionElement[] extensionElements;
	private BindingElement[] bindingElements;
	private DescriptionElement descElement;
	private String WSDLFilePath;
	private String WSDLFileConversionTarget;

	public WSDLParser(File file ){
		try {
			WSDLFactory factory;
			// create a WSDLReader instance using WSDLFactory
			factory = WSDLFactory.newInstance();
			WSDLReader reader = factory.newWSDLReader();
			reader.setFeature(WSDLReader.FEATURE_VALIDATION, true);
			// QName to represent top level Policy Element.
			QName type = new QName(
					"http://schemas.xmlsoap.org/ws/2004/09/policy", "Policy");
			// Retrieve ExtensionRegistry from WSDLReader
			ExtensionRegistry reg = reader.getExtensionRegistry();
			// register the ExtensionSerializer
			reg.registerSerializer(Description.class, type,
					new PolicyExtensionSerializer());
			// register the ExtensionDeserializer
			reg.registerDeserializer(DescriptionElement.class, type,
					new PolicyExtensionDeserializer());
			// register the ExtElementType
			reg.registerExtElementType(DescriptionElement.class, type,
					PolicyExtensionsImpl.class);
			Description descComp = reader.readWSDL(file.getPath());
			// Retrieve the descreption elements ;
			this.descElement = descComp.toElement();
			// Retrieve BindingElements from the 
			this.bindingElements = this.descElement.getBindingElements();
			// Retrieve ExtensionElements from DescriptionElement.
			this.extensionElements = this.getExtensionElements();
		} catch (WSDLException ex) {
			// A conversion to WSDL2.0 should be done here
			Logger.getLogger(WSDLParser.class.getName()).log(Level.SEVERE,
					null, ex);
			System.out.println("PROBLEM CREATION OF A WSDL PARSERS");
		}
		
	}
	public DescriptionElement WSDLBuilder(File file) {
		DescriptionElement descElem = null;
		try {
			WSDLFactory factory;
			// create a WSDLReader instance using WSDLFactory
			factory = WSDLFactory.newInstance();
			WSDLReader reader = factory.newWSDLReader();
			reader.setFeature(WSDLReader.FEATURE_VALIDATION, true);
			// QName to represent top level Policy Element.
			QName type = new QName(
					"http://schemas.xmlsoap.org/ws/2004/09/policy", "Policy");
			// Retrieve ExtensionRegistry from WSDLReader
			ExtensionRegistry reg = reader.getExtensionRegistry();
			// register the ExtensionSerializer
			reg.registerSerializer(Description.class, type,
					new PolicyExtensionSerializer());
			// register the ExtensionDeserializer
			reg.registerDeserializer(DescriptionElement.class, type,
					new PolicyExtensionDeserializer());
			// register the ExtElementType
			reg.registerExtElementType(DescriptionElement.class, type,
					PolicyExtensionsImpl.class);
			Description descComp = reader.readWSDL(file.getPath());
			// Retrieve ExtensionElements from DescriptionElement.
			descElem = descComp.toElement();
			this.setDescElement(descElem);
			this.setBindingElements(descElem.getBindingElements());
			this.setExtensionElements(descElem.getExtensionElements());
		} catch (WSDLException ex) {
			// A conversion to WSDL2.0 should be done here
			Logger.getLogger(WSDLParser.class.getName()).log(Level.SEVERE,
					null, ex);
			System.out.println("PROBLEM CREATION OF A WSDL PARSERS");
		}
		return descElem;
	}

	public InterfaceOperationElement[] getWSDLAction(DescriptionElement descElem) {
		InterfaceOperationElement[] result = new InterfaceOperationElement[descElem.getInterfaceElements().length];
		BindingElement[] bindingElements = descElem.getBindingElements();
		for (int i = 0; i < bindingElements.length; i++) {
			BindingElement bindingelement = bindingElements[i];
			InterfaceOperationElement[] interOpel = bindingelement
					.getInterfaceElement().getInterfaceOperationElements();
			for (int j = i; j < interOpel.length; j++) {
				result[j] = interOpel[j];
			
			}
		}
		return result;
	}

	public RampartPolicyData getPolicyData(DescriptionElement descElem) {
		RampartPolicyData policyData = null;
		ExtensionElement[] extEls = descElem.getExtensionElements();
		try {
			for (int i = 0; i < extEls.length; i++) {

				PolicyExtension policyExt = (PolicyExtension) extEls[i];
				// Retrieve policy Source As a Dom Element
				Element ele = (Element) policyExt.getXMLElement().getSource();
				Policy policy = (Policy) policyExt.getPolicy();
				ExactlyOne exactlyOne = (ExactlyOne) policy
						.getFirstPolicyComponent();
				All all = (All) exactlyOne.getFirstPolicyComponent();
				policyData = RampartPolicyBuilder.build(all.getAssertions());
			}
		} catch (WSSPolicyException ex) {
			Logger.getLogger(WSDLParser.class.getName()).log(Level.SEVERE,
					null, ex);
		}
		return policyData;
	}

	public String getWSDLFileConversionTarget() {
		return WSDLFileConversionTarget;
	}

	public void setWSDLFileConversionTarget(String WSDLFileConversionTarget) {
		this.WSDLFileConversionTarget = WSDLFileConversionTarget;
	}

	public String getWSDLFilePath() {
		return WSDLFilePath;
	}

	public void setWSDLFilePath(String WSDLFilePath) {
		this.WSDLFilePath = WSDLFilePath;
	}

	public BindingElement[] getBindingElements() {
		return bindingElements;
	}

	public void setBindingElements(BindingElement[] bindingElements) {
		this.bindingElements = bindingElements;
	}

	public ExtensionElement[] getExtensionElements() {
		return extensionElements;
	}

	public void setExtensionElements(ExtensionElement[] extensionElements) {
		this.extensionElements = extensionElements;
	}

	public DescriptionElement getDescElement() {
		return descElement;
	}

	public void setDescElement(DescriptionElement descElement) {
		this.descElement = descElement;
	}

/*	public static void main(String arts[]) {
		WSDLParser wsdlParser = new WSDLParser();
		wsdlParser.WSDLBuilder(new File("C:\\Users\\i068988\\Desktop\\wodenExt-eg\\wsdl\\wsdlFile\\test.wsdl"));
		DescriptionElement descElem = wsdlParser.getDescElement();
		RampartPolicyData policyData = wsdlParser.getPolicyData(descElem);
		InterfaceOperationElement[] actions = wsdlParser.getWSDLAction(descElem);
		for (int i = 0; i < actions.length; i++) {
			System.out.println(actions[i].getName().getLocalPart());
		}
	}*/
}
